home *** CD-ROM | disk | FTP | other *** search
/ Game Programming in C++ - Start to Finish / GameProgrammingS.iso / Peon / PeonSDK-Win32-1.0.0.exe / {app} / PeonMain / source / SceneRenderer.cpp < prev    next >
C/C++ Source or Header  |  2005-11-30  |  13KB  |  508 lines

  1.  
  2. #include "FileLogger.h"
  3. #include "IniConfigReader.h"
  4. #include "SceneRenderer.h"
  5.  
  6. namespace peon
  7. {
  8.     SceneRenderer::SceneRenderer()
  9.     {
  10.         m_pOGLSurface = NULL;
  11.         m_pActiveCamera = NULL;
  12.  
  13.         m_iDeviceWidth = 640;
  14.         m_iDeviceHeight= 480;
  15.         m_iBitsPerPixel= 16;
  16.         m_bWindowed    = true;
  17.  
  18.  
  19.     }
  20.  
  21.     SceneRenderer::~SceneRenderer()
  22.     {
  23.         unloadDevice();
  24.     }
  25.  
  26.     bool SceneRenderer::loadDevice( IniConfigReader* pConfig )
  27.     {
  28.         m_iDeviceWidth  = (int)pConfig->getInt("Application", "WindowWidth", 640);
  29.         m_iDeviceHeight = (int)pConfig->getInt("Application", "WindowHeight", 480);
  30.         m_iBitsPerPixel  = (int)pConfig->getInt("Application", "WindowDepth", 16);
  31.         m_bWindowed     = pConfig->getBool("Application", "Windowed", "TRUE");
  32.  
  33.         Uint32 iFlags;
  34.  
  35.         /////////////  we set the common flags here
  36.         iFlags    = SDL_OPENGL;                            // it's an openGL window
  37.         iFlags   |= SDL_HWPALETTE;                         // exclusive access to hardware colour palette
  38.         iFlags   |= SDL_RESIZABLE;                         // the window must be resizeable
  39.  
  40.         const SDL_VideoInfo *pVideoInfo = SDL_GetVideoInfo();  // query SDL for information about our video hardware
  41.  
  42.         if(pVideoInfo == NULL)                                  // if this query fails
  43.         {
  44.             FileLogger::getSingleton().logFatal("Renderer", "Error querying video information");
  45.             return false;
  46.         }
  47.  
  48.  
  49.         if( !m_bWindowed )
  50.         {
  51.             iFlags |= SDL_FULLSCREEN;
  52.         }
  53.  
  54.  
  55.         //we set the system dependant flags here
  56.         if(pVideoInfo -> hw_available)                        
  57.             iFlags |= SDL_HWSURFACE;
  58.         else
  59.             iFlags |= SDL_SWSURFACE;
  60.  
  61.         // Blitting is fast copying / moving /swapping of contiguous sections of memory
  62.         // more blitting info: http://www.csc.liv.ac.uk/~fish/HTML/blitzman/bm_blitter.html
  63.         if(pVideoInfo -> blit_hw)                               // is hardware blitting available
  64.             iFlags |= SDL_HWACCEL;
  65.  
  66.         SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );         // tell SDL that the GL drawing is going to be double buffered
  67.         SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE,   m_iBitsPerPixel);         // size of depth buffer
  68.         SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, 0);          // we aren't going to use the stencil buffer
  69.         SDL_GL_SetAttribute( SDL_GL_ACCUM_RED_SIZE, 0);        // this and the next three lines set the bits allocated per pixel -
  70.         SDL_GL_SetAttribute( SDL_GL_ACCUM_GREEN_SIZE, 0);      // - for the accumulation buffer to 0
  71.         SDL_GL_SetAttribute( SDL_GL_ACCUM_BLUE_SIZE, 0);
  72.         SDL_GL_SetAttribute( SDL_GL_ACCUM_ALPHA_SIZE, 0);
  73.  
  74.  
  75.         //log our information...for now just log the width x height x bit depth 
  76.         //of our requested surface
  77.         char strOutput[1024];
  78.         sprintf(strOutput, "Renderer surface: (%d x %d x %d)", m_iDeviceWidth, m_iDeviceHeight,
  79.             m_iBitsPerPixel);
  80.         FileLogger::getSingleton().logInfo("Renderer", strOutput );
  81.  
  82.  
  83.         if(m_bWindowed)
  84.         {
  85.             sprintf(strOutput, "Renderer surface: applying windowed");
  86.         }else
  87.             sprintf(strOutput, "Renderer surface: applying fullscreen");
  88.  
  89.     
  90.  
  91.         FileLogger::getSingleton().logInfo("Renderer", strOutput );
  92.  
  93.  
  94.         //This is the method which creates/generates our SDL_Surface
  95.         //according to the creation parameters we've set above. The
  96.         //SDL documentation is a good place to look for more information,
  97.         //but at the end of the day this should create our OpenGL 
  98.         //surface.
  99.         m_pOGLSurface = SDL_SetVideoMode( m_iDeviceWidth, m_iDeviceHeight, m_iBitsPerPixel, iFlags );
  100.         if(NULL == m_pOGLSurface)
  101.         {
  102.             FileLogger::getSingleton().logError("Renderer", "Failed to create the OpenGL surface!");
  103.             return false;
  104.         }
  105.  
  106.  
  107.         glClearColor( 0.0f, 0.0f, 1.0f, 1.0f );
  108.  
  109.  
  110.         const char *glVendor = (const char *) glGetString(GL_VENDOR);
  111.         const char *glRenderer = (const char *) glGetString(GL_RENDERER);
  112.         const char *glVersion = (const char *) glGetString(GL_VERSION);
  113.         //const char *glExtensions = (const char *) glGetString(GL_EXTENSIONS);
  114.  
  115.  
  116.  
  117.         sprintf(strOutput, "Renderer Vendor: %s", glVendor );
  118.         FileLogger::getSingleton().logInfo("Renderer", strOutput );
  119.  
  120.         sprintf(strOutput, "Renderer Stats: %s", glRenderer );
  121.         FileLogger::getSingleton().logInfo("Renderer", strOutput );
  122.  
  123.         sprintf(strOutput, "Renderer Version: %s", glVersion );
  124.         FileLogger::getSingleton().logInfo("Renderer", strOutput );
  125.  
  126.         //set some default OpenGL properties
  127.         glEnable( GL_TEXTURE_2D );
  128.         glDisable( GL_LIGHTING );
  129.  
  130.         glShadeModel( GL_SMOOTH );
  131.  
  132.         glClearDepth( 1.0f );
  133.         glEnable( GL_DEPTH_TEST );
  134.         glDepthFunc( GL_LEQUAL );
  135.  
  136.         glFrontFace( GL_CW );
  137.  
  138.  
  139.         glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
  140.  
  141.         float fAspect = (float)m_iDeviceWidth / (float)m_iDeviceHeight;
  142.  
  143.         m_pActiveCamera = new SceneCamera();
  144.  
  145.         m_pActiveCamera->setPerspectiveProj( fAspect, 1.0f, 100.0f );
  146.         m_pActiveCamera->setViewMatrix( Vector3( 0.0f, 0.0f, 10.0f ),
  147.                                         Vector3( 0.0f, 0.0f, 0.0f ),
  148.                                         Vector3( 0.0f, 1.0f, 0.0f ) );
  149.  
  150.         //since the Renderer object has been created, instantiate the CEGUI library
  151.         CEGUI::OpenGLRenderer* myRenderer = new CEGUI::OpenGLRenderer( 1024 );
  152.  
  153.         //instantiate the CEGUI subsystem with the OpenGL renderer
  154.         new CEGUI::System(myRenderer);
  155.  
  156.  
  157.  
  158.         return true;
  159.     }
  160.  
  161.     void SceneRenderer::unloadDevice()
  162.     {
  163.  
  164.         delete CEGUI::System::getSingletonPtr();
  165.  
  166.         PEON_DELETE( m_pActiveCamera );
  167.  
  168.         SDL_FreeSurface( m_pOGLSurface );
  169.  
  170.     }
  171.  
  172.     void SceneRenderer::flipDevice()
  173.     {
  174.         glFlush();
  175.         SDL_GL_SwapBuffers();
  176.     }
  177.  
  178.     bool SceneRenderer::clearDevice()
  179.     {
  180.         glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  181.         glLoadIdentity();
  182.  
  183.         return true;
  184.     }
  185.  
  186.     void SceneRenderer::drawPrim( DiffusePrim* pVertices, int count )
  187.     {
  188.         //push the current modelview matrix onto the matrix stack
  189.         glPushMatrix();
  190.  
  191.         //push the current color information onto the attribute stack
  192.         glPushAttrib( GL_CURRENT_BIT );
  193.         glLoadIdentity();
  194.  
  195.         //start pushing triangles through the pipeline
  196.         glBegin( GL_TRIANGLES );
  197.  
  198.         for(int i = 0; i < count; i++)
  199.         {
  200.             //specify the diffuse color component of the vertex    
  201.             glColor4f( pVertices[i].r, pVertices[i].g, 
  202.                 pVertices[i].b, pVertices[i].a );
  203.  
  204.             //specify the position component of the vertex    
  205.             glVertex3f( pVertices[i].x, pVertices[i].y, pVertices[i].z );
  206.  
  207.         }
  208.  
  209.         //finished 
  210.         glEnd();
  211.  
  212.         glPopAttrib();
  213.         glPopMatrix();
  214.  
  215.     }
  216.  
  217.     void SceneRenderer::drawPrim( DiffuseTexPrim* pVertices, int count )
  218.     {
  219.         //push the current modelview matrix onto the matrix stack
  220.         glPushMatrix();
  221.  
  222.         //push the current color information onto the attribute stack
  223.         glPushAttrib( GL_CURRENT_BIT );
  224.         glLoadIdentity();
  225.  
  226.         //start pushing triangles through the pipeline
  227.         glBegin( GL_TRIANGLES );
  228.  
  229.         for(int i = 0; i < count; i++)
  230.         {
  231.             //specify the diffuse color component of the vertex    
  232.             glColor4f( pVertices[i].r, pVertices[i].g, 
  233.                 pVertices[i].b, pVertices[i].a );
  234.  
  235.             glTexCoord2f( pVertices[i].tu, pVertices[i].tv );
  236.  
  237.             //specify the position component of the vertex    
  238.             glVertex3f( pVertices[i].x, pVertices[i].y, pVertices[i].z );
  239.  
  240.         }
  241.  
  242.         //finished 
  243.         glEnd();
  244.  
  245.         glPopAttrib();
  246.         glPopMatrix();
  247.  
  248.     }
  249.  
  250.     void SceneRenderer::drawPrim( NormalDiffuseTexPrim* pVertices, int count )
  251.     {
  252.         //push the current modelview matrix onto the matrix stack
  253.         glPushMatrix();
  254.  
  255.         //push the current color information onto the attribute stack
  256.         glPushAttrib( GL_CURRENT_BIT );
  257.         glLoadIdentity();
  258.  
  259.         //start pushing triangles through the pipeline
  260.         glBegin( GL_TRIANGLES );
  261.  
  262.         for(int i = 0; i < count; i++)
  263.         {
  264.             glNormal3f( pVertices[i].nx, pVertices[i].ny, pVertices[i].nz );
  265.  
  266.             //specify the diffuse color component of the vertex    
  267.             glColor4f( pVertices[i].r, pVertices[i].g, 
  268.                 pVertices[i].b, pVertices[i].a );
  269.  
  270.             glTexCoord2f( pVertices[i].tu, pVertices[i].tv );
  271.  
  272.             //specify the position component of the vertex    
  273.             glVertex3f( pVertices[i].x, pVertices[i].y, pVertices[i].z );
  274.  
  275.         }
  276.  
  277.         //finished 
  278.         glEnd();
  279.  
  280.         glPopAttrib();
  281.         glPopMatrix();
  282.  
  283.     }
  284.  
  285.     void SceneRenderer::drawQuads( NormalDiffuseTexPrim* pVertices, int count )
  286.     {
  287.         OutputDebugString("drawing quads\n");
  288.  
  289.         //push the current modelview matrix onto the matrix stack
  290.         glPushMatrix();
  291.  
  292.         //push the current color information onto the attribute stack
  293.         glPushAttrib( GL_CURRENT_BIT );
  294.         glLoadIdentity();
  295.  
  296.         //start pushing triangles through the pipeline
  297.         glBegin( GL_QUADS );
  298.  
  299.         for(int i = 0; i < count; i++)
  300.         {
  301.             glNormal3f( pVertices[i].nx, pVertices[i].ny, pVertices[i].nz );
  302.  
  303.             //specify the diffuse color component of the vertex    
  304.             glColor4f( pVertices[i].r, pVertices[i].g, 
  305.                        pVertices[i].b, pVertices[i].a );
  306.  
  307.             glTexCoord2f( pVertices[i].tu, pVertices[i].tv );
  308.  
  309.             //specify the position component of the vertex    
  310.             glVertex3f( pVertices[i].x, pVertices[i].y, pVertices[i].z );
  311.  
  312.         }
  313.  
  314.         //finished 
  315.         glEnd();
  316.  
  317.         glPopAttrib();
  318.         glPopMatrix();
  319.  
  320.     }
  321.  
  322.  
  323.     void SceneRenderer::setLight(int light_slot, const SceneLight& oLight)
  324.     {
  325.         
  326.  
  327.         GLenum eLight = GL_LIGHT0;
  328.  
  329.         switch( light_slot )
  330.         {
  331.         case 1:
  332.             eLight = GL_LIGHT1;
  333.             break;
  334.         case 2:
  335.             eLight = GL_LIGHT2;
  336.             break;
  337.         case 3:
  338.             eLight = GL_LIGHT3;
  339.             break;
  340.         case 4:
  341.             eLight = GL_LIGHT4;
  342.             break;
  343.         case 5: 
  344.             eLight = GL_LIGHT5;
  345.             break;
  346.         case 6:
  347.             eLight = GL_LIGHT6;
  348.             break;
  349.         case 7:
  350.             eLight = GL_LIGHT7;
  351.             break;
  352.         }
  353.  
  354.  
  355.         float ambient[4];
  356.         float diffuse[4];
  357.         float position[4];
  358.  
  359.         ambient[0] = oLight.m_vecAmbient.x;
  360.         ambient[1] = oLight.m_vecAmbient.y;
  361.         ambient[2] = oLight.m_vecAmbient.z;
  362.         ambient[3] = oLight.m_vecAmbient.w;
  363.  
  364.         diffuse[0] = oLight.m_vecDiffuse.x;
  365.         diffuse[1] = oLight.m_vecDiffuse.y;
  366.         diffuse[2] = oLight.m_vecDiffuse.z;
  367.         diffuse[3] = oLight.m_vecDiffuse.w;
  368.  
  369.         position[0] = oLight.m_vecDirection.x;
  370.         position[1] = oLight.m_vecDirection.y;
  371.         position[2] = oLight.m_vecDirection.z;
  372.         position[3] = oLight.m_vecDirection.w;
  373.  
  374.  
  375.         glLightfv( eLight, GL_AMBIENT,  ambient );       // Set our ambience values (Default color without direct light)
  376.         glLightfv( eLight, GL_DIFFUSE,  diffuse );        // Set our diffuse color (The light color)
  377.  
  378.  
  379.         glLightfv( eLight, GL_POSITION, position );    // This Sets our light position
  380.  
  381.         glEnable( eLight );                                // Turn this light on
  382.  
  383.         //if we're setting a light, then at least we should
  384.         //enable lighting
  385.         glEnable( GL_LIGHTING );
  386.         glEnable( GL_COLOR_MATERIAL );
  387.  
  388.  
  389.         m_oLights[light_slot] = oLight;
  390.  
  391.  
  392.     }
  393.  
  394.     SceneTexture* SceneRenderer::loadTexture( const String& strFilename, bool bAlpha,
  395.         bool bMipMaps, bool bRepeat)
  396.     {
  397.         SceneTexture* pTex = new SceneTexture();
  398.  
  399.         pTex->loadImage( strFilename, bAlpha, bMipMaps, bRepeat );
  400.  
  401.         return( pTex );
  402.     }
  403.  
  404.  
  405. /*
  406.     void SceneRenderer::setTexture( SceneTexture* pTex )
  407.     {
  408.         glBindTexture(GL_TEXTURE_2D, pTex->getTex() );
  409.  
  410.     }
  411. */
  412.  
  413.     SceneFont* SceneRenderer::loadFont( int char_width, int char_height, int char_spacing )
  414.     {
  415.         SceneFont* pFont = new SceneFont();
  416.  
  417.         pFont->loadFont( char_width, char_height, char_spacing );
  418.  
  419.         return( pFont );
  420.     }
  421.  
  422.     bool SceneRenderer::isExtensionSupported( const String& ext )
  423.     {
  424.         int pos = 0;
  425.         bool supported = false;
  426.  
  427.         int n = (int)ext.length();
  428.  
  429.         String extensions ((char *)glGetString(GL_EXTENSIONS));
  430.  
  431.         while( !supported )
  432.         {
  433.             if ( extensions.compare(pos, n, ext) >= 0 )                    // if the string `ext' is a part of the string `extensions'
  434.             {
  435.                 return true;
  436.             }
  437.             
  438.             pos = extensions.find(' ' , pos) + 1;
  439.  
  440.             if( pos <= 0 )
  441.                 return false;
  442.         }
  443.  
  444.         return false;
  445.     }
  446.  
  447.     /**
  448.     * http://www.devolution.com/pipermail/sdl/2000-September/030013.html
  449.     */
  450.     void SceneRenderer::getScreenCapture()
  451.     {
  452.         SDL_Surface *temp;
  453.         unsigned char *pixels;
  454.         int i;
  455.  
  456.         static int file_count = 0;
  457.  
  458.         char strFileName[1024];
  459.         sprintf(strFileName, "screen_capture_%d.bmp", file_count);
  460.  
  461.     
  462.         temp = SDL_CreateRGBSurface(SDL_SWSURFACE, m_pOGLSurface->w, m_pOGLSurface->h, 24,
  463. #if SDL_BYTEORDER == SDL_LIL_ENDIAN
  464.         0x000000FF, 0x0000FF00, 0x00FF0000, 0
  465. #else
  466.         0x00FF0000, 0x0000FF00, 0x000000FF, 0
  467. #endif
  468.         );
  469.  
  470.         if (temp == NULL)
  471.             return;
  472.  
  473.         pixels = new unsigned char[3 * m_pOGLSurface->w * m_pOGLSurface->h];
  474.         if (pixels == NULL)
  475.         {
  476.             SDL_FreeSurface(temp);
  477.             return;
  478.         }
  479.  
  480.         glReadPixels(0, 0, m_pOGLSurface->w, m_pOGLSurface->h, GL_RGB, GL_UNSIGNED_BYTE, pixels);
  481.  
  482.         for (i=0; i<m_pOGLSurface->h; i++)
  483.             memcpy(((char *) temp->pixels) + temp->pitch * i, pixels + 3*m_pOGLSurface->w * (m_pOGLSurface->h-i-1), m_pOGLSurface->w*3);
  484.         
  485.  
  486.         PEON_DELETE_ARRAY( pixels );
  487.  
  488.         SDL_SaveBMP(temp, strFileName);
  489.         SDL_FreeSurface(temp);
  490.  
  491.         file_count++;
  492.  
  493.     }
  494.  
  495.  
  496.     void SceneRenderer::getProjectionMatrix( Matrix44& pMat )
  497.     {
  498.         
  499.         //glGetFloatv( GL_PROJECTION_MATRIX, pMat.m );
  500.  
  501.     }
  502.  
  503.     void SceneRenderer::getModelViewMatrix( Matrix44& pMat )
  504.     {
  505.         //glGetFloatv( GL_MODELVIEW_MATRIX, pMat.m );
  506.     }
  507.  
  508. }